home *** CD-ROM | disk | FTP | other *** search
/ InterCD 2000 September / september_2000.iso / intercd / root / ^Linux / WindowMaker / util / getstyle.c < prev    next >
Encoding:
C/C++ Source or Header  |  1999-09-17  |  12.6 KB  |  621 lines

  1. /* getstyle.c - outputs style related options from WindowMaker to stdout
  2.  *
  3.  *  WindowMaker window manager
  4.  * 
  5.  *  Copyright (c) 1997, 1998 Alfredo K. Kojima
  6.  * 
  7.  *  This program is free software; you can redistribute it and/or modify
  8.  *  it under the terms of the GNU General Public License as published by
  9.  *  the Free Software Foundation; either version 2 of the License, or
  10.  *  (at your option) any later version.
  11.  *
  12.  *  This program is distributed in the hope that it will be useful,
  13.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.  *  GNU General Public License for more details.
  16.  *
  17.  *  You should have received a copy of the GNU General Public License
  18.  *  along with this program; if not, write to the Free Software
  19.  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, 
  20.  *  USA.
  21.  */
  22.  
  23.  
  24. #define PROG_VERSION "getstyle (Window Maker) 0.4"
  25.  
  26.  
  27.  
  28. #include <stdlib.h>
  29. #include <stdio.h>
  30. #include <proplist.h>
  31. #include <string.h>
  32. #include <unistd.h>
  33. #include <string.h>
  34. #include <pwd.h>
  35. #include <limits.h>
  36. #include <assert.h>
  37.  
  38. #ifndef PATH_MAX
  39. #define PATH_MAX  1024
  40. #endif
  41.  
  42. #include "../src/wconfig.h"
  43.  
  44. /* table of style related options */
  45. static char *options[] = {
  46.     "TitleJustify",    
  47.     "ClipTitleFont",
  48.     "WindowTitleFont",    
  49.     "MenuTitleFont",    
  50.     "MenuTextFont",    
  51.     "IconTitleFont",
  52.     "DisplayFont",
  53.     "LargeDisplayFont",
  54.     "HighlightColor",    
  55.     "HighlightTextColor",
  56.     "ClipTitleColor",
  57.     "CClipTitleColor",
  58.     "FTitleColor",    
  59.     "PTitleColor",    
  60.     "UTitleColor",    
  61.     "FTitleBack",    
  62.     "PTitleBack",    
  63.     "UTitleBack",
  64.     "ResizebarBack",
  65.     "MenuTitleColor",    
  66.     "MenuTextColor",    
  67.     "MenuDisabledColor", 
  68.     "MenuTitleBack",    
  69.     "MenuTextBack",
  70.     "IconBack",    
  71.     "IconTitleColor",
  72.     "IconTitleBack",
  73.     "MenuStyle",
  74.     NULL
  75. };
  76.  
  77.  
  78. /* table of theme related options */
  79. static char *theme_options[] = {
  80.     "WorkspaceBack",
  81.     NULL
  82. };
  83.  
  84.  
  85.  
  86.  
  87. char *ProgName;
  88.  
  89. proplist_t PixmapPath = NULL;
  90.  
  91. char *ThemePath = NULL;
  92.  
  93.  
  94. void
  95. print_help()
  96. {
  97.     printf("Usage: %s [OPTIONS] [FILE]\n", ProgName);
  98.     puts("Retrieves style/theme configuration and output to FILE or to stdout");
  99.     puts("");
  100.     puts("  -t, --theme-options    output theme related options when producing a style file");
  101.     puts("  -p, --pack        produce output as a theme pack");
  102.     puts("  --help        display this help and exit");
  103.     puts("  --version        output version information and exit");
  104. }
  105.  
  106.  
  107. char*
  108. globalDefaultsPathForDomain(char *domain)
  109. {
  110.     char path[1024];
  111.     char *tmp;
  112.  
  113.     sprintf(path, "%s/WindowMaker/%s", SYSCONFDIR, domain);
  114.  
  115.     tmp = malloc(strlen(path)+2);
  116.     assert(tmp!=NULL);
  117.     strcpy(tmp, path);
  118.  
  119.     return tmp;
  120. }
  121.  
  122.  
  123. char*
  124. defaultsPathForDomain(char *domain)
  125. {
  126.     char path[1024];
  127.     char *gspath, *tmp;
  128.  
  129.     gspath = getenv("GNUSTEP_USER_ROOT");
  130.     if (gspath) {
  131.     strcpy(path, gspath);
  132.     strcat(path, "/");
  133.     } else {
  134.     char *home;
  135.     
  136.     home = getenv("HOME");
  137.     if (!home) {
  138.         printf("%s:could not get HOME environment variable!\n", ProgName);
  139.         exit(0);
  140.     }
  141.     strcpy(path, home);
  142.     strcat(path, "/GNUstep/");
  143.     }
  144.     strcat(path, DEFAULTS_DIR);
  145.     strcat(path, "/");
  146.     strcat(path, domain);
  147.  
  148.     tmp = malloc(strlen(path)+2);
  149.     strcpy(tmp, path);
  150.     
  151.     return tmp;
  152. }
  153.  
  154.  
  155. BOOL
  156. StringCompareHook(proplist_t pl1, proplist_t pl2)
  157. {
  158.     char *str1, *str2;
  159.  
  160.     str1 = PLGetString(pl1);
  161.     str2 = PLGetString(pl2);
  162.  
  163.     if (strcasecmp(str1, str2)==0)
  164.       return YES;
  165.     else
  166.       return NO;
  167. }
  168.  
  169.  
  170. void
  171. abortar(char *reason)
  172. {
  173.     char buffer[4000];
  174.  
  175.     printf("%s: %s\n", ProgName, reason);
  176.  
  177.     if (ThemePath) {
  178.     printf("Removing unfinished theme pack\n");
  179.     sprintf(buffer, "/bin/rm -fr \"%s\"", ThemePath);
  180.     
  181.     if (system(buffer)!=0) {
  182.         printf("%s: could not execute command %s\n", ProgName, buffer);
  183.     }
  184.     }
  185.     exit(1);
  186. }
  187.  
  188.  
  189.  
  190.  
  191. char*
  192. wgethomedir()
  193. {
  194.     char *home = getenv("HOME");
  195.     struct passwd *user;
  196.  
  197.     if (home)
  198.       return home;
  199.     
  200.     user = getpwuid(getuid());
  201.     if (!user) {
  202.     char buffer[80];
  203.     
  204.     sprintf(buffer, "could not get password entry for UID %i", getuid()); 
  205.     perror(buffer);
  206.     return "/";
  207.     }
  208.     if (!user->pw_dir) {
  209.     return "/";
  210.     } else {
  211.     return user->pw_dir;
  212.     }
  213. }
  214.  
  215.  
  216. void*
  217. wmalloc(int size)
  218. {
  219.     void *tmp;
  220.     
  221.     tmp = malloc(size);
  222.     if (!tmp) {
  223.     abortar("out of memory");
  224.     }
  225.     
  226.     return tmp;
  227. }
  228.  
  229.  
  230. char*
  231. wstrdup(char *str)
  232. {
  233.     char *tmp;
  234.     
  235.     tmp = wmalloc(strlen(str)+1);
  236.  
  237.     strcpy(tmp, str);
  238.  
  239.     return tmp;
  240. }
  241.  
  242.  
  243. static char*
  244. getuserhomedir(char *username)
  245. {
  246.     struct passwd *user;
  247.     
  248.     user = getpwnam(username);
  249.     if (!user) {
  250.     char buffer[100];
  251.  
  252.     sprintf(buffer,"could not get password entry for user %s", username);
  253.     perror(buffer);
  254.     return NULL;
  255.     }
  256.     if (!user->pw_dir) {
  257.     return "/";
  258.     } else {
  259.     return user->pw_dir;
  260.     }
  261. }
  262.  
  263.  
  264.  
  265.  
  266. char*
  267. wexpandpath(char *path)
  268. {
  269.     char buffer2[PATH_MAX+2];
  270.     char buffer[PATH_MAX+2];
  271.     int i;
  272.  
  273.     memset(buffer, 0, PATH_MAX+2);
  274.     
  275.     if (*path=='~') {
  276.     char *home;
  277.     
  278.     path++;
  279.     if (*path=='/' || *path==0) {
  280.         home = wgethomedir();
  281.         strcat(buffer, home);
  282.     } else {
  283.         int j;
  284.         j = 0;
  285.         while (*path!=0 && *path!='/') {
  286.         buffer2[j++] = *path;
  287.         buffer2[j] = 0;
  288.         path++;
  289.         }
  290.         home = getuserhomedir(buffer2);
  291.         if (!home)
  292.         return NULL;
  293.         strcat(buffer, home);
  294.     }
  295.     }
  296.     
  297.     i = strlen(buffer);
  298.  
  299.     while (*path!=0) {
  300.     char *tmp;
  301.     
  302.     if (*path=='$') {
  303.         int j = 0;
  304.         path++;
  305.         /* expand $(HOME) or $HOME style environment variables */
  306.         if (*path=='(') {
  307.         path++;
  308.         while (*path!=0 && *path!=')') {
  309.             buffer2[j++] = *(path++);
  310.             buffer2[j] = 0;
  311.                 }
  312.                 if (*path==')')
  313.                     path++;
  314.         tmp = getenv(buffer2);
  315.         if (!tmp) {
  316.             buffer[i] = 0;
  317.             strcat(buffer, "$(");
  318.             strcat(buffer, buffer2);
  319.             strcat(buffer, ")");
  320.             i += strlen(buffer2)+3;
  321.         } else {
  322.             strcat(buffer, tmp);
  323.             i += strlen(tmp);
  324.         }
  325.         } else {
  326.         while (*path!=0 && *path!='/') {
  327.             buffer2[j++] = *(path++);
  328.             buffer2[j] = 0;
  329.         }
  330.         tmp = getenv(buffer2);
  331.         if (!tmp) {
  332.             strcat(buffer, "$");
  333.             strcat(buffer, buffer2);
  334.             i += strlen(buffer2)+1;
  335.         } else {
  336.             strcat(buffer, tmp);
  337.             i += strlen(tmp);
  338.         }
  339.         }        
  340.     } else {
  341.         buffer[i++] = *path;
  342.         path++;
  343.     }
  344.     }
  345.     
  346.     return wstrdup(buffer);
  347. }
  348.  
  349.  
  350.  
  351. char*
  352. wfindfileinarray(proplist_t paths, char *file)
  353. {
  354.     int i;
  355.     char *path;
  356.     int len, flen;
  357.     char *fullpath;
  358.  
  359.     if (!file)
  360.     return NULL;
  361.     
  362.     if (*file=='/' || *file=='~' || !paths || !PLIsArray(paths) 
  363.     || PLGetNumberOfElements(paths)==0) {
  364.     if (access(file, R_OK)<0) {
  365.         fullpath = wexpandpath(file);
  366.         if (!fullpath)
  367.         return NULL;
  368.         
  369.         if (access(fullpath, R_OK)<0) {
  370.         free(fullpath);
  371.         return NULL;
  372.         } else {
  373.         return fullpath;
  374.         }
  375.     } else {
  376.         return wstrdup(file);
  377.     }
  378.     }
  379.  
  380.     flen = strlen(file);
  381.     for (i=0; i < PLGetNumberOfElements(paths); i++) {
  382.     proplist_t tmp;
  383.     char *dir;
  384.  
  385.     tmp = PLGetArrayElement(paths, i);
  386.     if (!PLIsString(tmp) || !(dir = PLGetString(tmp)))
  387.         continue;
  388.  
  389.     len = strlen(dir);
  390.     path = wmalloc(len+flen+2);
  391.     path = memcpy(path, dir, len);
  392.     path[len]=0;
  393.     strcat(path, "/");
  394.     strcat(path, file);
  395.     /* expand tilde */
  396.     fullpath = wexpandpath(path);
  397.     free(path);
  398.     if (fullpath) {
  399.         /* check if file is readable */
  400.         if (access(fullpath, R_OK)==0) {
  401.         return fullpath;
  402.         }
  403.         free(fullpath);
  404.     }
  405.     }
  406.     return NULL;
  407. }
  408.  
  409.  
  410.  
  411.  
  412. void
  413. copyFile(char *dir, char *file)
  414. {
  415.     char buffer[4000];
  416.     
  417.     sprintf(buffer, "/bin/cp \"%s\" \"%s\"", file, dir);
  418.     if (system(buffer)!=0) {
  419.     printf("%s: could not copy file %s\n", ProgName, file);
  420.     }
  421. }
  422.  
  423.  
  424. void
  425. findCopyFile(char *dir, char *file)
  426. {
  427.     char *fullPath;
  428.  
  429.     fullPath = wfindfileinarray(PixmapPath, file);
  430.     if (!fullPath) {
  431.     char buffer[4000];
  432.  
  433.     sprintf(buffer, "coould not find file %s", file);
  434.     abortar(buffer);
  435.     }
  436.     copyFile(dir, fullPath);
  437.     free(fullPath);
  438. }
  439.  
  440.  
  441. char*
  442. makeThemePack(proplist_t style, char *themeName)
  443. {
  444.     proplist_t keys;
  445.     proplist_t key;
  446.     proplist_t value;
  447.     int i;
  448.     char *themeDir;
  449.  
  450.     themeDir = wmalloc(strlen(themeName)+50);
  451.     sprintf(themeDir, "%s.themed", themeName);
  452.     ThemePath = themeDir;
  453.     {
  454.     char *tmp;
  455.     
  456.     tmp = wmalloc(strlen(themeDir)+20);
  457.     sprintf(tmp, "/bin/mkdir \"%s\"", themeDir);
  458.     if (system(tmp)!=0) {
  459.         printf("%s: could not create directory %s. Probably there's already a theme with that name in this directory.\n", ProgName, themeDir);
  460.         exit(1);
  461.     }
  462.     free(tmp);
  463.     }
  464.     keys = PLGetAllDictionaryKeys(style);
  465.  
  466.     for (i = 0; i < PLGetNumberOfElements(keys); i++) {
  467.     key = PLGetArrayElement(keys, i);
  468.  
  469.     value = PLGetDictionaryEntry(style, key);
  470.     if (value && PLIsArray(value) && PLGetNumberOfElements(value) > 2) {
  471.         proplist_t type;
  472.         char *t;
  473.  
  474.         type = PLGetArrayElement(value, 0);
  475.         t = PLGetString(type);
  476.         if (t && (strcasecmp(t, "tpixmap")==0
  477.               || strcasecmp(t, "spixmap")==0
  478.               || strcasecmp(t, "cpixmap")==0
  479.               || strcasecmp(t, "mpixmap")==0
  480.               || strcasecmp(t, "tdgradient")==0
  481.               || strcasecmp(t, "tvgradient")==0
  482.               || strcasecmp(t, "thgradient")==0)) {
  483.         proplist_t file;
  484.         char *p;
  485.         char *newPath;
  486.  
  487.         file = PLGetArrayElement(value, 1);
  488.  
  489.         p = strrchr(PLGetString(file), '/');
  490.         if (p) {
  491.             copyFile(themeDir, PLGetString(file));
  492.  
  493.             newPath = wstrdup(p+1);
  494.             PLRemoveArrayElement(value, 1);
  495.             PLInsertArrayElement(value, PLMakeString(newPath), 1);
  496.             free(newPath);
  497.         } else {
  498.             findCopyFile(themeDir, PLGetString(file));
  499.         }
  500.         }
  501.     }
  502.     }
  503.  
  504.     return themeDir;
  505. }
  506.  
  507.  
  508. int 
  509. main(int argc, char **argv)
  510. {
  511.     proplist_t prop, style, key, val;
  512.     char *path;
  513.     int i, theme_too=0;
  514.     int make_pack = 0;
  515.     char *style_file = NULL;
  516.  
  517.  
  518.     ProgName = argv[0];
  519.  
  520.     if (argc>1) {
  521.     for (i=1; i<argc; i++) {
  522.         if (strcmp(argv[i], "-p")==0
  523.         || strcmp(argv[i], "--pack")==0) {
  524.         make_pack = 1;
  525.         theme_too = 1;
  526.         } else if (strcmp(argv[i], "-t")==0
  527.                || strcmp(argv[i], "--theme-options")==0) {
  528.                 theme_too++;
  529.         } else if (strcmp(argv[i], "--help")==0) {
  530.         print_help();
  531.         exit(0);
  532.         } else if (strcmp(argv[i], "--version")==0) {
  533.         puts(PROG_VERSION);
  534.         exit(0);
  535.         } else {
  536.         if (style_file!=NULL) {
  537.             printf("%s: invalid argument '%s'\n", argv[0], 
  538.                style_file[0]=='-' ? style_file : argv[i]);
  539.             printf("Try '%s --help' for more information\n", argv[0]);
  540.             exit(1);
  541.         }
  542.                 style_file = argv[i];
  543.             }
  544.         }
  545.     }
  546.     
  547.     if (make_pack && !style_file) {
  548.     printf("%s: you must supply a name for the theme pack\n", ProgName);
  549.     exit(1);
  550.     }
  551.  
  552.     PLSetStringCmpHook(StringCompareHook);
  553.  
  554.     path = defaultsPathForDomain("WindowMaker");
  555.  
  556.     prop = PLGetProplistWithPath(path);
  557.     if (!prop) {
  558.     printf("%s:could not load WindowMaker configuration file \"%s\".\n", 
  559.            ProgName, path);
  560.     exit(1);
  561.     }
  562.     free(path);
  563.  
  564.     /* get global value */
  565.     path = globalDefaultsPathForDomain("WindowMaker");
  566.     val = PLGetProplistWithPath(path);
  567.     if (val) {
  568.     PLMergeDictionaries(val, prop);
  569.     PLRelease(prop);
  570.     prop = val;
  571.     }
  572.  
  573.     style = PLMakeDictionaryFromEntries(NULL, NULL, NULL);
  574.  
  575.  
  576.     for (i=0; options[i]!=NULL; i++) {
  577.         key = PLMakeString(options[i]);
  578.  
  579.         val = PLGetDictionaryEntry(prop, key);
  580.         if (val)
  581.             PLInsertDictionaryEntry(style, key, val);
  582.     }
  583.  
  584.     val = PLGetDictionaryEntry(prop, PLMakeString("PixmapPath"));
  585.     if (val)
  586.         PixmapPath = val;
  587.  
  588.     if (theme_too) {
  589.         for (i=0; theme_options[i]!=NULL; i++) {
  590.             key = PLMakeString(theme_options[i]);
  591.  
  592.             val = PLGetDictionaryEntry(prop, key);
  593.             if (val)
  594.                 PLInsertDictionaryEntry(style, key, val);
  595.         }    
  596.     }
  597.  
  598.     if (make_pack) {
  599.     char *path;
  600.  
  601.     makeThemePack(style, style_file);
  602.  
  603.     path = wmalloc(strlen(ThemePath)+32);
  604.     strcpy(path, ThemePath);
  605.     strcat(path, "/style");
  606.     PLSetFilename(style, PLMakeString(path));
  607.     PLSave(style, NO);
  608.     } else {
  609.     if (style_file) {
  610.         val = PLMakeString(style_file);
  611.         PLSetFilename(style, val);
  612.         PLSave(style, NO);
  613.     } else {
  614.         puts(PLGetDescriptionIndent(style, 0));
  615.     }
  616.     }
  617.     exit(0);
  618. }
  619.  
  620.  
  621.